/**
 * @file spi_bsp.c
 * @author  xiaowine (xiaowine@sina.cn)
 * @brief
 * @version 01.00
 * @date    2021-07-07
 *
 * @copyright Copyright (c) {2020}  xiaowine
 *
 * @par ????:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2021-07-07 <td>1.0     <td>wangh     <td>??
 * </table>
 * ******************************************************************
 * *                   .::::
 * *                 .::::::::
 * *                ::::::::::
 * *             ..:::::::::::
 * *          '::::::::::::
 * *            .:::::::::
 * *       '::::::::::::::..        女神助攻,流量冲天
 * *            ..::::::::::::.     永不宕机,代码无bug
 * *          ``:::::::::::::::
 * *           ::::``:::::::::'        .:::
 * *          ::::'   ':::::'       .::::::::
 * *        .::::'      ::::     .:::::::'::::
 * *       .:::'       :::::  .:::::::::' ':::::
 * *      .::'        :::::.:::::::::'      ':::::
 * *     .::'         ::::::::::::::'         ``::::
 * * ...:::           ::::::::::::'              ``::
 * *```` ':.          ':::::::::'                  ::::.
 * *                   '.:::::'                    ':'````.
 * ******************************************************************
 */

/* Private includes ----------------------------------------------------------*/
#include "spi_bsp.h"

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

/* Public define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/
#ifdef SPI_USING_DMA
volatile uint8_t spiDmaRxBuffer[2][BufferSize] = {0};
volatile uint8_t spiDmaTxBuffer[2][BufferSize] = {0xa0, 0xa1, 7, 15, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
#endif
/* Public variables ---------------------------------------------------------*/

/* Private function prototypes -----------------------------------------------*/
#ifdef SPI_USING_DMA
static void MDA1NVIC_CFG(SPI_TypeDef *SPIx);
#endif
SPI_InitTypeDef SPI1_InitStructure;
SPI_InitTypeDef SPI2_InitStructure;
/* Private user code ---------------------------------------------------------*/

/*********************************************************
 * @name   spiGpioConfig
 * @brief  spi gpio and port bank clock initilization
 * @calls  none
 * @called spi_initDMA()
 * @param  None
 * @retval None
 *********************************************************/
static void spiGpioConfig(SPI_TypeDef *SPIx)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    if (SPIx == SPI1) {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
        /* Configure SPI_MASTER pins: SCK and MOSI */
        GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_7 | GPIO_Pin_5;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOA, &GPIO_InitStructure);

        /* Configure SPI_MASTER NSS pin */
        GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_4;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        /* Configure SPI_MASTER MISO pin */
        GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        GPIO_SetBits(GPIOA, GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7);
    } else if (SPIx == SPI2) {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
        /* Configure SPI_MASTER pins: SCK and MOSI */
        GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_13 | GPIO_Pin_15;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOB, &GPIO_InitStructure);

        /* Configure SPI_MASTER NSS pin */
        GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_12;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        /* Configure SPI_MASTER MISO pin */
        GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_14;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_SetBits(GPIOB, GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
    }
}

void spiInit(SPI_TypeDef *SPIx)
{ 
    if (SPIx == SPI1) {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
        spiGpioConfig(SPI1);
        SPI_I2S_DeInit(SPI1);
        /* SPI_MASTER configuration ------------------------------------------------------*/
        SPI1_InitStructure.SPI_Direction         = SPI_Direction_2Lines_FullDuplex;
        SPI1_InitStructure.SPI_Mode              = SPI_Mode_Master;
        SPI1_InitStructure.SPI_DataSize          = SPI_DataSize_8b;
        SPI1_InitStructure.SPI_CPOL              = SPI_CPOL_Low;
        SPI1_InitStructure.SPI_CPHA              = SPI_CPHA_1Edge;
        SPI1_InitStructure.SPI_NSS               = SPI_NSS_Soft;
        SPI1_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
        SPI1_InitStructure.SPI_FirstBit          = SPI_FirstBit_MSB;
        SPI1_InitStructure.SPI_CRCPolynomial     = 7;
        SPI_Init(SPI1, &SPI1_InitStructure);

        /* Enable SPI_MASTER NSS output for master mode */
        // SPI_SSOutputCmd(SPI1, ENABLE);
        /* Enable SPI_MASTER */
        SPI_Cmd(SPI1, ENABLE);
        SPI_I2S_ReceiveData(SPI1);
    } else if (SPIx == SPI2) {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
        spiGpioConfig(SPI2);
        SPI_I2S_DeInit(SPI2);
        /* SPI_MASTER configuration ------------------------------------------------------*/
        SPI2_InitStructure.SPI_Direction         = SPI_Direction_2Lines_FullDuplex;
        SPI2_InitStructure.SPI_Mode              = SPI_Mode_Master;
        SPI2_InitStructure.SPI_DataSize          = SPI_DataSize_8b;
        SPI2_InitStructure.SPI_CPOL              = SPI_CPOL_Low;
        SPI2_InitStructure.SPI_CPHA              = SPI_CPHA_1Edge;
        SPI2_InitStructure.SPI_NSS               = SPI_NSS_Soft;
        SPI2_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
        SPI2_InitStructure.SPI_FirstBit          = SPI_FirstBit_MSB;
        SPI2_InitStructure.SPI_CRCPolynomial     = 7;
        SPI_Init(SPI2, &SPI2_InitStructure);

        /* Enable SPI_MASTER NSS output for master mode */
        // SPI_SSOutputCmd(SPI2, ENABLE);
        /* Enable SPI_MASTER */
        SPI_Cmd(SPI2, ENABLE);

        SPI_I2S_ReceiveData(SPI2);
        
        SPIx_ReadWriteByte(SPI2, 0xff );  //启动传输
    }
}

// SPI 速度设置函数
// SpeedSet:
// SPI_BaudRatePrescaler_2   2分频   (SPI 36M@sys 72M)
// SPI_BaudRatePrescaler_8   8分频   (SPI 9M@sys 72M)
// SPI_BaudRatePrescaler_16  16分频  (SPI 4.5M@sys 72M)
// SPI_BaudRatePrescaler_256 256分频 (SPI 281.25K@sys 72M)

void SPI2_SetSpeed(u8 SpeedSet)
{
    SPI2_InitStructure.SPI_BaudRatePrescaler = SpeedSet;
    SPI_Init(SPI2, &SPI2_InitStructure);
    SPI_Cmd(SPI2, ENABLE);
}

/*************************************************************************/
//函数功能：初始化SPI总线，设置SPI总线为0模式
/*************************************************************************/
void SPI_BUS_Init(void)
{
    spiInit(SPI2);                                               //初始化SPI
    SPI2_SetSpeed( SPI_BaudRatePrescaler_8);  //设置为10M时钟,高速模式
}
/*************************************************************************/
//函数功能：设置CS信号为高电平
/*************************************************************************/
void SPI_CS_H(void)
{
    GPIO_SetBits(GPIOB, GPIO_Pin_12);
}
/*************************************************************************/
//函数功能：设置CS信号为低电平
/*************************************************************************/
void SPI_CS_L(void)
{
    GPIO_ResetBits(GPIOB, GPIO_Pin_12);
}
// SPIx 读写一个字节
// TxData:要写入的字节
//返回值:读取到的字节
int8_t SPIx_ReadWriteByte(SPI_TypeDef *SPIx, uint8_t TxData)
{
    int retry = 0;
    while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET)  //检查指定的SPI标志位设置与否:发送缓存空标志位
    {
        retry++;
        if (retry > 200)
            return 0;
    }
    SPI_I2S_SendData(SPIx, TxData);  //通过外设SPIx发送一个数据
    retry = 0;

    while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET)  //检查指定的SPI标志位设置与否:接受缓存非空标志位
    {
        retry++;
        if (retry > 200)
            return 0;
    }
    return SPI_I2S_ReceiveData(SPIx);  //返回通过SPIx最近接收的数据
}

/*********************************************************
 * @name   spiDMAConfig
 * @brief  spi gpio and port bank clock initilization
 * @calls  none
 * @called spi_initDMA
 * @param  None
 * @retval None
 *********************************************************/
#ifdef SPI_USING_DMA
void spiDMAConfig(SPI_TypeDef *SPIx)
{
    DMA_InitTypeDef DMA_InitStructure;
    if (SPIx == SPI1) { /* Enable SPI DMA clock */
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
        MDA1NVIC_CFG(SPIx);
        /* Enable SPI_RX DMA  */
        DMA_DeInit(DMA1_Channel2);
        DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&SPI1->DR);
        DMA_InitStructure.DMA_MemoryBaseAddr     = (uint32_t)spiDmaRxBuffer[SPI1_INDEX];
        DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralSRC;
        DMA_InitStructure.DMA_BufferSize         = transSize;
        DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;
        DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
        DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte;
        DMA_InitStructure.DMA_Mode               = DMA_Mode_Normal;
        DMA_InitStructure.DMA_Priority           = DMA_Priority_VeryHigh;
        DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;
        DMA_Init(DMA1_Channel2, &DMA_InitStructure);
        /* Enable DMA1 Channel4 */
        DMA_Cmd(DMA1_Channel2, DISABLE);

        /* Enable SPI_TX DMA  */
        DMA_DeInit(DMA1_Channel3);
        DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&SPI1->DR);
        DMA_InitStructure.DMA_MemoryBaseAddr     = (uint32_t)spiDmaTxBuffer[SPI1_INDEX];
        DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralDST;
        DMA_InitStructure.DMA_BufferSize         = transSize;
        DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;
        DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
        DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte;
        DMA_InitStructure.DMA_Mode               = DMA_Mode_Normal;
        DMA_InitStructure.DMA_Priority           = DMA_Priority_VeryHigh;
        DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;
        DMA_Init(DMA1_Channel3, &DMA_InitStructure);
        /* Enable DMA1 Channel5 */
        DMA_Cmd(DMA1_Channel3, DISABLE);

        DMA_ClearFlag(DMA1_FLAG_GL4);
        DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, ENABLE);
    } else if (SPIx == SPI2) {
        /* Enable SPI DMA clock */
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
        MDA1NVIC_CFG(SPIx);
        /* Enable SPI_RX DMA  */
        DMA_DeInit(DMA1_Channel4);
        DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&SPI2->DR);
        DMA_InitStructure.DMA_MemoryBaseAddr     = (uint32_t)spiDmaRxBuffer[SPI2_INDEX];
        DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralSRC;
        DMA_InitStructure.DMA_BufferSize         = transSize;
        DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;
        DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
        DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte;
        DMA_InitStructure.DMA_Mode               = DMA_Mode_Normal;
        DMA_InitStructure.DMA_Priority           = DMA_Priority_VeryHigh;
        DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;
        DMA_Init(DMA1_Channel4, &DMA_InitStructure);
        /* Enable DMA1 Channel4 */
        DMA_Cmd(DMA1_Channel4, DISABLE);

        /* Enable SPI_TX DMA  */
        DMA_DeInit(DMA1_Channel5);
        DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&SPI2->DR);
        DMA_InitStructure.DMA_MemoryBaseAddr     = (uint32_t)spiDmaTxBuffer[SPI2_INDEX];
        DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralDST;
        DMA_InitStructure.DMA_BufferSize         = transSize;
        DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;
        DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
        DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte;
        DMA_InitStructure.DMA_Mode               = DMA_Mode_Normal;
        DMA_InitStructure.DMA_Priority           = DMA_Priority_VeryHigh;
        DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;
        DMA_Init(DMA1_Channel5, &DMA_InitStructure);
        /* Enable DMA1 Channel5 */
        DMA_Cmd(DMA1_Channel5, DISABLE);

        DMA_ClearFlag(DMA1_FLAG_GL4);
        DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);
    }
}
#endif
/**
 * @brief  Configure the nested vectored interrupt controller.
 * @param  None
 * @retval None
 */
#ifdef SPI_USING_DMA
static void MDA1NVIC_CFG(SPI_TypeDef *SPIx)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    if (SPIx == SPI1) {
        /* Enable DMA1 channel2 IRQ Channel */
        NVIC_InitStructure.NVIC_IRQChannel                   = DMA1_Channel2_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
    } else if (SPIx == SPI2) {
        /* Enable DMA1 channel4 IRQ Channel */
        NVIC_InitStructure.NVIC_IRQChannel                   = DMA1_Channel4_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
    }
}
#endif
/*********************************************************
 * @name   spi_initDMA
 * @brief  spi2 gpio and port bank clock initilization
 * @calls  spi2GpioConfig RCC_APB1PeriphClockCmd spi2DMAConfig()
 * @called
 * @param  None
 * @retval None
 *********************************************************/
#ifdef SPI_USING_DMA
void spi_initDMA(SPI_TypeDef *SPIx)
{
    SPI_InitTypeDef SPI_InitStructure;
    if (SPIx == SPI1) {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
        spiGpioConfig(SPI1);
        spiDMAConfig(SPI1);
        SPI_I2S_DeInit(SPI1);
        /* SPI_MASTER configuration ------------------------------------------------------*/
        SPI_InitStructure.SPI_Direction         = SPI_Direction_2Lines_FullDuplex;
        SPI_InitStructure.SPI_Mode              = SPI_Mode_Master;
        SPI_InitStructure.SPI_DataSize          = SPI_DataSize_8b;
        SPI_InitStructure.SPI_CPOL              = SPI_CPOL_Low;
        SPI_InitStructure.SPI_CPHA              = SPI_CPHA_1Edge;
        SPI_InitStructure.SPI_NSS               = SPI_NSS_Soft;
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
        SPI_InitStructure.SPI_FirstBit          = SPI_FirstBit_MSB;
        SPI_InitStructure.SPI_CRCPolynomial     = 7;
        SPI_Init(SPI1, &SPI_InitStructure);

        /* Enable SPI_MASTER NSS output for master mode */
        // SPI_SSOutputCmd(SPI1, ENABLE);
        /* Enable SPI_MASTER */
        SPI_Cmd(SPI1, ENABLE);
        SPI_I2S_ReceiveData(SPI1);
        /* Enable SPI_DMA request */
        SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx | SPI_I2S_DMAReq_Tx, ENABLE);
        // spi2Start();
        /* Enable DMA1 Channel4 */
        DMA_Cmd(DMA1_Channel2, ENABLE);
        /* Enable DMA1 Channel5 */
        DMA_Cmd(DMA1_Channel3, ENABLE);
    } else if (SPIx == SPI2) {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
        spiGpioConfig(SPI2);
        spiDMAConfig(SPI2);
        SPI_I2S_DeInit(SPI2);
        /* SPI_MASTER configuration ------------------------------------------------------*/
        SPI_InitStructure.SPI_Direction         = SPI_Direction_2Lines_FullDuplex;
        SPI_InitStructure.SPI_Mode              = SPI_Mode_Master;
        SPI_InitStructure.SPI_DataSize          = SPI_DataSize_8b;
        SPI_InitStructure.SPI_CPOL              = SPI_CPOL_Low;
        SPI_InitStructure.SPI_CPHA              = SPI_CPHA_1Edge;
        SPI_InitStructure.SPI_NSS               = SPI_NSS_Soft;
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
        SPI_InitStructure.SPI_FirstBit          = SPI_FirstBit_MSB;
        SPI_InitStructure.SPI_CRCPolynomial     = 7;
        SPI_Init(SPI2, &SPI_InitStructure);

        /* Enable SPI_MASTER NSS output for master mode */
        // SPI_SSOutputCmd(SPI2, ENABLE);
        /* Enable SPI_MASTER */
        SPI_Cmd(SPI2, ENABLE);
        SPI_I2S_ReceiveData(SPI2);
        /* Enable SPI_DMA request */
        SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx | SPI_I2S_DMAReq_Tx, ENABLE);
        // spi2Start();
        /* Enable DMA1 Channel4 */
        DMA_Cmd(DMA1_Channel4, ENABLE);
        /* Enable DMA1 Channel5 */
        DMA_Cmd(DMA1_Channel5, ENABLE);
    }
}

void spiSend(SPI_TypeDef *SPIx)
{
    uint16_t TxIdx = 0;
    int      spiIndex;
    if (SPIx == SPI1) {
        spiIndex = SPI1_INDEX;
    } else if (SPIx == SPI2) {
        spiIndex = SPI2_INDEX;
    }

    /* Transfer procedure */
    while (TxIdx < BufferSize) {
        /* Wait for SPI_MASTER Tx buffer empty */
        while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET)
            ;
        /* Send SPI_MASTER data */
        SPI_I2S_SendData(SPIx, spiDmaTxBuffer[spiIndex][TxIdx++]);
    }
}

void spiStartDMA(SPI_TypeDef *SPIx)
{
    if (SPIx == SPI1) {
        DMA_ClearFlag(DMA1_FLAG_GL2);
        DMA_ClearFlag(DMA1_FLAG_GL3);
        /* Enable DMA1 Channel2 */
        DMA_Cmd(DMA1_Channel2, DISABLE);
        /* Enable DMA1 Channel3 */
        DMA_Cmd(DMA1_Channel3, DISABLE);
        DMA_SetCurrDataCounter(DMA1_Channel2, transSize);
        DMA_SetCurrDataCounter(DMA1_Channel3, transSize);
        /* Enable SPI_MASTER */
        SPI_Cmd(SPI1, ENABLE);
        SPI1_CS(Bit_RESET);
        /* Enable DMA1 Channel2 */
        DMA_Cmd(DMA1_Channel2, ENABLE);
        /* Enable DMA1 Channel3 */
        DMA_Cmd(DMA1_Channel3, ENABLE);
    } else if (SPIx == SPI2) {
        DMA_ClearFlag(DMA1_FLAG_GL4);
        DMA_ClearFlag(DMA1_FLAG_GL5);
        /* Enable DMA1 Channel4 */
        DMA_Cmd(DMA1_Channel4, DISABLE);
        /* Enable DMA1 Channel5 */
        DMA_Cmd(DMA1_Channel5, DISABLE);
        DMA_SetCurrDataCounter(DMA1_Channel4, transSize);
        DMA_SetCurrDataCounter(DMA1_Channel5, transSize);
        /* Enable SPI_MASTER */
        SPI_Cmd(SPI2, ENABLE);
        SPI2_CS(Bit_RESET);
        /* Enable DMA1 Channel4 */
        DMA_Cmd(DMA1_Channel4, ENABLE);
        /* Enable DMA1 Channel5 */
        DMA_Cmd(DMA1_Channel5, ENABLE);
    }
}

/**
 * @brief  This function handles DMA1 Channel 2 interrupt request.
 * @param  None
 * @retval None
 */
void DMA1_Channel2_IRQHandler(void)
{
    /* Test on DMA1 Channel4 Transfer Complete interrupt */
    if (DMA_GetITStatus(DMA1_IT_TC2)) {
        SPI1_CS(Bit_SET);
        spiRxCallBack(SPI1);
        /* Get Current Data Counter value after complete transfer */
        // CurrDataCounterEnd = DMA_GetCurrDataCounter(DMA1_Channel2);
        /* Clear DMA1 Channel4 Half Transfer, Transfer Complete and Global interrupt pending bits */
        DMA_ClearITPendingBit(DMA1_IT_GL2);
    }
}

/**
 * @brief  This function handles DMA1 Channel 4 interrupt request.
 * @param  None
 * @retval None
 */
void DMA1_Channel4_IRQHandler(void)
{
    /* Test on DMA1 Channel4 Transfer Complete interrupt */
    if (DMA_GetITStatus(DMA1_IT_TC4)) {
        SPI2_CS(Bit_SET);
        GPIO_SetBits(GPIOB, GPIO_Pin_12);
        spiRxCallBack(SPI2);
        /* Get Current Data Counter value after complete transfer */
        // CurrDataCounterEnd = DMA_GetCurrDataCounter(DMA1_Channel4);
        /* Clear DMA1 Channel4 Half Transfer, Transfer Complete and Global interrupt pending bits */
        DMA_ClearITPendingBit(DMA1_IT_GL4);
    }
}

#endif
/*********************************************************************************************************/
